<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        
    </style>
</head>
<body>
    
</body>
<script>
    // 设计模式

    // 单例模式：单个实例，就一个对象，每次创建都需要重新设计
    // const obj = {};
    // const obj3 = {};
    // const obj2 = new Object();
    // const phone1 = {
    //     color:"白色",
    //     size:10,
    //     strong: "200g",
    //     call:function(){},
    //     sms:function(){}
    // }
    // const phone2 = {
    //     color:"白色",
    //     size:10,
    //     strong: "200g",
    //     call:function(){},
    //     sms:function(){}
    // }
    
    // 工厂模式：提前设计好一个模型，根据模型中的属性和方法，只需要确定不同的信息即可批量创建同特点对象
    // function createPhone(c, s){
    //     // 原料
    //     const phone = {};
    //     // 加工
    //     phone.color = c;
    //     phone.size = s;
    //     phone.call = function(){}
    //     // 出厂
    //     return phone;
    // }

    // const p1 = createPhone("白色", "10");
    // const p2 = createPhone("红色", "11");

    // console.log(p1);
    // console.log(p2);
    // console.log(p1 === p2);

    // 抽象工厂模式：在工厂模式的基础上，将公共属性或信息，再次进行抽象，形成更细节化的工厂模式
    // function createWhitePhone(s){
    //     return new createPhone("白色", s);
    // }

    // const wp1 = createWhitePhone("10寸");
    // const wp2 = createWhitePhone("9寸");
    // const wp3 = createWhitePhone("8寸");
    // console.log(wp1);
    // console.log(wp2);
    // console.log(wp3);
    // console.log(wp3 === wp1);

    // ============

        

    // 工厂模式：
    // 问题：语法复杂
    // function createPhone(c, s){
    //     // 原料
    //     const phone = {};
    //     // 加工
    //     phone.color = c;
    //     phone.size = s;
    //     phone.telCall = function(){};
    //     // 出厂
    //     return phone;
    // }

    // const p1 = createPhone("白色", "10");
    // const p2 = createPhone("红色", "11");

    // console.log(p1);
    // console.log(p2);
    // console.log(p1 === p2);

    // // 冗余方法
    // console.log(p1.telCall);
    // console.log(p2.telCall);

    // console.log(p1.telCall === p2.telCall);


    // 所有的内置，都不存在冗余方法
    // const arr1 = new Array();
    // const arr2 = new Array();

    // console.log(arr1 === arr2);

    // console.log(arr1.push);
    // console.log(arr2.push);

    // console.log(arr1.push === arr2.push);


    // 传统的工厂模式，被淘汰了，替换方案是官方内置的工厂模式

    // 内置的工厂模式（自定义构造函数，自定义本地对象）
    // function fn(){
    //     // 加工
    //     this.name = "华为";
    //     this.telCall = function(){}
    // }
    // 函数自身有一个属性叫prototype，是对象类型的数据
    // fn.prototype.show = function(){ 'show' }

    // new的原理：
        // 1. 创建一个新对象
        // 2. 修改了函数内的this指向，指向这个新对象
        // 3. 执行这个函数内的所有代码
        // 4. 将这个新对象的**原型指针**指向了函数的prototype
        // 5. 检测原函数是否主动返回对象，如果没有，返回这个新对象

    // const f1 = new fn();
    // const f2 = new fn();
    // console.log(f1);
    // console.log(f2);
    // console.log(f1 === f2);
    // console.log(f1.telCall);
    // console.log(f2.telCall);
    // console.log(f2.telCall === f1.telCall);
    // console.log(f1.show)
    // console.log(f2.show)
    // console.log(f1.show === f2.show)

    // new自带原料，自动出厂

    // 原型链：子原型可以访问父原型的方法或属性

    // 行业习惯：构造函数的命名规则：大驼峰

    // ========

    // 工厂模式创建对象的最终语法

    // 类
    function CreatePhone(c,s){
        this.color = c;
        this.size = s;
        // this.telCall();
    }
    // 接口规范（interface）
    CreatePhone.prototype.telCall = function(){
        console.log(`${this.color}的${this.size}的手机在打电话`);
    }
    // 实例
    const p1 = new CreatePhone("白色", "10寸");
    const p2 = new CreatePhone("黑色", "9寸");
    console.log(p1);
    console.log(p2);
    console.log(p2 === p1);
    p1.telCall();
    p2.telCall();
    console.log(p1.telCall === p2.telCall);

    // 属性写在构造函数内
    // 方法写在构造函数的prototype上

    // 构造函数内的this和prototype上的方法内的this，指向同一个对象

    // 接口规范（interface）约束了类的功能
    // 类约束了实例的属性






</script>
</html>